﻿#include<iostream>
#include<afxwin.h>
#include <ctime>
#include <future>
#include <initializer_list>
#include <type_traits>
#include <atomic>
#include "ini.h"
#include "gs-public.h"

using namespace std;

#define KEY_PRESSED(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x0001) ? 1:0) //如果为真，表示按下过
#define KEY_PRESSING(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)  //如果为真，表示正处于按下状态

struct g_config {
	string className;
	string script;
	int times;
    int pauseKey;
    bool isLog;
	friend std::ostream& operator <<(std::ostream& os, g_config const& a) {
		return os << '\n'
			<< "className  \t= " << a.className << "" << '\n'
			<< "script  \t= " << a.script << "" << '\n'
			<< "times  \t\t= " << a.times << "" << '\n'
			<< "pauseKey  \t= " << a.pauseKey << "" << '\n'
			<< "isLog  \t\t= " << a.isLog << "" << '\n'
			;
	}
};

// 程序全局变量
g_params params;

// 配置参数
g_config config;

// 程序开始运行的时间戳
long long beginTime;

// 读取配置文件
void loadConfig() {
    ZIni ini("config.ini");
    config.className = ini.get("common", "className", "UnrealWindow");
    config.script = ini.get("common", "script", "test");
    config.times = ini.getInt("common", "times", 1);
    config.pauseKey = ini.getInt("common", "pauseKey", 0);
    config.isLog = ini.getInt("common", "isLog", 0);
    std::cout << "已加载配置：" << config;
}

// 延迟t毫秒
void sleep(string script, int t) {
    if (config.isLog) {
        cout << script + "：延迟" + to_string(t) + "毫秒\n";
    }
    Sleep(t);
}

// 按下按键
void keyDown(string script, char key) {
    while (params.pause) {
        Sleep(1000);
    }
    if (config.isLog) {
        cout << script + "：按下" + key + "\n";
    }
    keyDown(params.hwnd, key);
}

// 初始化程序
void init(string className) {
    // 脚本信息
    SetConsoleTitle(L"MagicKeyboard v1.1");

    // 提示信息
    std::cout << "\t   MagicKeyboard v1.1  --by gosick39（幻塔-学习交流Q群：565943273）" << endl << endl;
    std::cout << "  注意：本程序仅学习使用，禁止商用！" << endl << endl;
    cout << "\t使用说明：" << endl;
    cout << "\t    1、请在进入游戏后打开此程序" << endl;
    cout << "\t    2、可在config.ini文件中配置要启用的脚本" << endl;
    cout << "\t    3、可在scripts文件夹中自定义脚本（Q/E/R/1即按下按键，2000延迟2000毫秒...）" << endl;
    loadConfig();
    // 获取窗口句柄
    params.hwnd = getWindow(config.className);
    params.cwnd = CWnd::FromHandle(params.hwnd);
    // 窗口置前
    //SetForegroundWindow(params.hwnd);
    // 获取当前时间
    params.beginTime = get_timestamp();
    // 初始化暂停键
    if (config.pauseKey == 1) {
        params.pauseName = "TAB";
        params.pauseVal = VK_TAB;

    }
    else if (config.pauseKey == 2) {
        params.pauseName = "Enter";
        params.pauseVal = VK_RETURN;
    }
}

void handle(string script) {
    cout << "开始执行 '" + script + "' \n";
    HWND hwnd = params.hwnd;
    CWnd* cWnd = params.cwnd;

    // 读取脚本
    string path = "scripts\\" + script + ".txt";
    vector<string> ss = readFileTexts(path);

    int times = 0;
    while (true) {
        // 开始执行
        for (string s : ss) {
            if (s[0] == '_') {
                s = s.erase(0, 1);
                if (isNumeric(s)) {
                    int t = atoi(s.c_str());
                    if (s.length() == 1) {
                        keyDown(script, 0x60 + t);
                    }
                    else {
                        sleep(script, t);
                    }
                }
                else if (s.length() == 1) {
                    keyDown(script, s[0]);
                }
            }
            else {
                if (isNumeric(s)) {
                    int t = atoi(s.c_str());
                    if (s.length() == 1) {
                        keyDown(script, 0x30 + t);
                    }
                    else {
                        sleep(script, t);
                    }
                }
                else if (s.length() == 1) {
                    keyDown(script, s[0]);
                }
            }
        }
        times++;
        if (times >= config.times) {
            std::cout << "已执行" << times << "次，执行结束" << endl;
            system("pause");
            exit(0);
        }
    }
}

void handleScripts() {
    vector<string> scripts = split(config.script, ",");
    for (string s : scripts) {
        thread first(handle, s); // 开启线程
        first.detach();
    }
}

int main() {
    init(config.className);
    vector<string> scripts = split(config.script, ",");
    std::cout << endl;
    // 如果开启暂停功能
    if (config.pauseKey > 0) {
        std::cout << "按下" << params.pauseName << "键开始/暂停" << endl;
        while (1) {
            if (KEY_PRESSED(params.pauseVal)) {
                // 开启线程
                for (int i = 0; i < scripts.size(); i++) {
                    thread thi(handle, scripts[i]);
                    thi.detach();
                }
                while (1) {
                    if (KEY_PRESSED(params.pauseVal)) {
                        if (params.pause) {
                            params.pause = false;
                            cout << "已继续" << endl;
                        }
                        else {
                            params.pause = true;
                            cout << "已暂停" << endl;
                        }
                    }
                    Sleep(500);
                }
            }
            Sleep(1000);
        }
    }
    else {
        // 开启线程
        for (int i = 1; i < scripts.size(); i++) {
            thread thi(handle, scripts[i]);
            thi.detach();
        }
        string s0 = scripts[0];
        thread th0(handle, s0);
        th0.join();
    }
}